package day03.nio03;

import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

/**
 * 自定义协议进行NIO通信，服务器端
 * 协议规则：数据长度+#+数据内容
 */
public class SSCDemo03 {
    private static Scanner scanner = new Scanner(System.in);
    public static void main(String[] args) throws Exception {
        //1.创建ServerSocketChannel
        ServerSocketChannel ssc = ServerSocketChannel.open();
        //2.开启非阻塞模式
        ssc.configureBlocking(false);
        //3.绑定端口
        ssc.socket().bind(new java.net.InetSocketAddress(9999));
        //4.创建Selector
        Selector selector = Selector.open();
        //5.将ServerSocketChannel注册到Selector上
        ssc.register(selector, SelectionKey.OP_ACCEPT);
        //6.循环处理
        while(true){
            //--进行选择操作，如果没有任何键就绪，则阻塞，直到有键就绪为止
            selector.select();
            //--获取选择到的就绪的键
            Set<SelectionKey> set = selector.selectedKeys();
            //--处理就绪的键
            Iterator<SelectionKey> it = set.iterator();
            while(it.hasNext()){
                //--获取键
                SelectionKey sk = it.next();
                //--判断键的类型
                if(sk.isAcceptable()){
                    //--获取键对应的ServerSocketChannel
                    ServerSocketChannel selc_ssc = (ServerSocketChannel)sk.channel();
                    //--接受连接
                    SocketChannel sc = null;
                    while(sc==null){
                        sc = selc_ssc.accept();
                    }
                    //--设置非阻塞模式
                    sc.configureBlocking(false);
                    //--将SocketChannel注册到Selector上
                    sc.register(selector, SelectionKey.OP_READ);
                }else if(sk.isConnectable()){

                }else if(sk.isWritable()){
                    System.out.println("[服务器]请输入要发送的内容：");
                    String msg = scanner.nextLine();
                    String str = msg.getBytes("utf-8").length+"#"+msg;
                    //--发送数据
                    SocketChannel selc_sc = (SocketChannel)sk.channel();
                    ByteBuffer buf = ByteBuffer.wrap(str.getBytes("utf-8"));
                    while(buf.hasRemaining()){
                        selc_sc.write(buf);
                    }
                    //--注册读取事件
                    selc_sc.register(selector, SelectionKey.OP_READ);
                }else if(sk.isReadable()){
                    //--获取键对应的SocketChannel
                    SocketChannel selc_sc = (SocketChannel)sk.channel();
                    //--读取数据
                    String lenData = "";
                    ByteBuffer tempBuf = ByteBuffer.allocate(1);
                    while(!lenData.endsWith("#")){
                        selc_sc.read(tempBuf);
                        lenData += new String(tempBuf.array(),"utf-8");
                        tempBuf.clear();
                    }
                    int len = Integer.parseInt(lenData.substring(0, lenData.length()-1));
                    ByteBuffer buf = ByteBuffer.allocate(len);
                    selc_sc.read(buf);
                    String str = new String(buf.array(),"utf-8");
                    System.out.println(str);
                    //--注册写出事件
                    selc_sc.register(selector, SelectionKey.OP_WRITE);
                }else{

                }
                //--处理完毕后，一定要将键移除
                it.remove();
            }
        }
    }
}
